package com.lc.admin.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lc.admin.bean.Dept;
import com.lc.admin.bean.LoginUserDetails;
import com.lc.admin.constants.DeptConstants;
import com.lc.admin.constants.RedisKeyConstants;
import com.lc.admin.dto.DeptSaveDto;
import com.lc.admin.mapper.DeptMapper;
import com.lc.admin.service.DeptService;
import com.lc.admin.utils.StringUtils;
import com.lc.admin.utils.UserThreadLocal;
import com.lc.admin.vo.DeptSelectVo;
import com.lc.admin.vo.DeptTableVo;
import com.lc.admin.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    DeptMapper deptMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    ObjectMapper objectMapper = new ObjectMapper();

    @Cacheable(value=RedisKeyConstants.DEPT_ALL)
    @Override
    public DeptTableVo findAll() throws Exception {
        DeptTableVo deptTableVos =  new DeptTableVo();
        // 所有的部门
        List<Dept> depts = deptMapper.findAll();

        // 递归组装数据
        for (Dept dept : depts) {
            if (dept.getParentDeptNo().equals(DeptConstants.ROOT_DEPT_NO)) {
                deptTableVos.setId(dept.getId() + "");
                deptTableVos.setDeptName(dept.getDeptName());
                deptTableVos.setChildren(new ArrayList<>());
                recur(depts, dept.getDeptNo(), deptTableVos.getChildren());
            }
        }
        System.out.println("磁盘IO查询....");
        return deptTableVos;
    }

    @Override
    public List<UserVo> findAllUser() {
        return deptMapper.findAllUser();
    }

    @Cacheable(value=RedisKeyConstants.DEPT_SECOND)
    @Override
    public List<DeptSelectVo> findSecondDept() {
        List<DeptSelectVo> deptSelectVos = new ArrayList<>();
        // 所有的部门
        List<Dept> depts = deptMapper.findAll();
        // 找到一级部门添加到集合中
        for (Dept dept : depts) {
            if (dept.getParentDeptNo().equals(DeptConstants.ROOT_DEPT_NO)) {
                DeptSelectVo root = DeptSelectVo.builder()
                        .label(dept.getDeptName())
                        .value(Long.parseLong(dept.getDeptNo()))
                        .children(new ArrayList<>())
                        .build();
                deptSelectVos.add(root);

                for (Dept dept1 : depts) {
                    if (dept1.getParentDeptNo().equals(dept.getDeptNo())) {
                        DeptSelectVo second = DeptSelectVo.builder()
                                .label(dept1.getDeptName())
                                .value(Long.parseLong(dept1.getDeptNo()))
                                .build();

                        root.getChildren().add(second);
                    }
                }
            }
        }
        return deptSelectVos;
    }

    @CacheEvict(value={RedisKeyConstants.DEPT_ALL, RedisKeyConstants.DEPT_SECOND},allEntries = true)
    @Override
    public void save(DeptSaveDto deptSaveDto) {
        try {
            String userJson = UserThreadLocal.getSubject();
            ObjectMapper om = new ObjectMapper();
            LoginUserDetails loginUserDetails = om.readValue(userJson, LoginUserDetails.class);

            Dept dept = new Dept();
            dept.setCreateBy(loginUserDetails.getId());
            // 把Dto转成Bean
            BeanUtils.copyProperties(deptSaveDto, dept);

            // 解决部门没有编号的问题
            Random r = new Random();
            int i = r.nextInt(1000000000);
            dept.setDeptNo(i + "");

            deptMapper.save(dept);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    @CacheEvict(value={RedisKeyConstants.DEPT_ALL, RedisKeyConstants.DEPT_SECOND},allEntries = true)
    @Transactional
    @Override
    public void del(Long id) {
        // 1、先根据id查询当前部门详情
        Dept dept = deptMapper.findById(id);

        // 2、从详情获取deptNo，查询所有的子部门
        List<Long> ids = deptMapper.findIdsByDeptNo(dept.getDeptNo());

        // 3、删除所有的子部门
        if (null != ids && ids.size() > 0) {
            for (Long aLong : ids) {
                deptMapper.delById(aLong);
            }
        }

        // 4、删除当前部门
        deptMapper.delById(id);
    }

    @Override
    public Dept findById(Long id) {
        return deptMapper.findById(id);
    }

    // 递归删除文件的案例   非空文件夹不允许直接删除
    // 找儿子，封装起来
    private void recur(List<Dept> depts, String deptNo, List<DeptTableVo> target) {
        for (Dept dept : depts) {
            System.out.println(".......");
            if (dept.getParentDeptNo().equals(deptNo)) {
                DeptTableVo deptTableVo = new DeptTableVo();
                deptTableVo.setId(dept.getId() + "");
                deptTableVo.setDeptName(dept.getDeptName());
                deptTableVo.setChildren(new ArrayList<>());
                target.add(deptTableVo);

                recur(depts, dept.getDeptNo(), deptTableVo.getChildren());
            }
        }
    }


}
